package com.china.school;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

import java.io.IOException;

@SpringBootApplication
public class ResourceLoaderTest implements ResourceLoaderAware {

    private static   ResourceLoader resourceLoader;

    @Autowired
    private     ResourceLoader resourceLoader2;

    //获取项目路径下的资源
    @Value("${classpath:FileSystemResourceTest.xml}")
//    @Value("${file://Spring-Resources/src/main/resources/FileSystemResourceTest.xml}")
    private Resource resourceLoader3;

    public Resource getResourceLoader3() {
        return resourceLoader3;
    }

    public void setResourceLoader3(Resource resourceLoader3) {
        this.resourceLoader3 = resourceLoader3;
    }



    public static void main(String[] args) throws IOException {
        /**
         请注意：
         1  所有的容器都实现了 ResourceLoader ===>>ApplicationContext extends ResourcePatternResolver
         2   ResourcePatternResolver  extends ResourceLoader
         3 因此 PathMatchingResourcePatternResolver  implements ResourcePatternResolver
        4 针对 ClassPathXmlApplicationContext，该代码返回 ClassPathResource。
         如果针对 FileSystemXmlApplicationContext 实例运行相同的方法，则会返回 FileSystemResource。
         对于 WebApplicationContext，它将返回一个 ServletContextResource。同样地，它将为每个 context 返回适当的对象。

         5 当然你也可以如下，并不依赖于容器的类型
         Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");

         6 ResourcePatternResolver 接口是对 ResourceLoader 接口的扩展，它定义了将位置模式（例如，Ant风格的路径模式）解析为 Resource 对象的策略。

         7 PathMatchingResourcePatternResolver 是一个独立的实现，
         可以在 ApplicationContext 之外使用，也可以被 ResourceArrayPropertyEditor 用于填充 Resource[] bean属性。
         PathMatchingResourcePatternResolver 能够将指定的资源位置路径解析为一个或多个匹配的 Resource 对象。源路径可以是一个简单的路径，
         它与目标 Resource 有一对一的映射，或者可以包含特殊的 classpath*: 前缀和/或内部Ant风格的正则表达式
         （使用 Spring 的 org.springframework.util.AntPathMatcher 工具匹配）。后者都是有效的通配符。

         8 任何标准 ApplicationContext 中的默认 ResourceLoader 实际上是 PathMatchingResourcePatternResolver 的一个实例，
         它实现了 ResourcePatternResolver 接口。ApplicationContext 实例本身也是如此，它也实现了 ResourcePatternResolver
         接口并委托给默认的 PathMatchingResourcePatternResolver。


         */


        ConfigurableApplicationContext ctx = SpringApplication.run(ResourceLoaderTest.class);
        System.out.println("验证ResourceLoader其实就是Spring容器 " + (ctx == ResourceLoaderTest.resourceLoader));
        System.out.println("autowired注入， 验证ResourceLoader其实就是Spring容器 " + (ctx == ctx.getBean(ResourceLoaderTest.class).getResourceLoader2()));

//        System.out.println("@Value注入Resource "+  ctx.getBean(ValueTest.class).getResourceLoader3().getFile().getAbsolutePath()) ;

        System.out.println(ctx.getResource("file:///Spring-Resources/src/main/resources/FileSystemResourceTest.xml").exists());
        System.out.println(ctx.getResource("classpath:FileSystemResourceTest.xml").exists());

    }

    public ResourceLoader getResourceLoader2() {
        return resourceLoader2;
    }




    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        ResourceLoaderTest.resourceLoader = resourceLoader;
    }



    @Component
    public static class ValueTest{
        //获取项目路径下的资源
//        @Value("${classpath:FileSystemResourceTest.xml}")
    @Value("${file:///Spring-Resources/src/main/resources/FileSystemResourceTest.xml}")
        private Resource resourceLoader3;

        public Resource getResourceLoader3() {
            return resourceLoader3;
        }

        public void setResourceLoader3(Resource resourceLoader3) {
            this.resourceLoader3 = resourceLoader3;
        }
    }
}
